package xin.nick.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
import xin.nick.common.entity.UserGrantedAuthority;
import xin.nick.entity.*;
import xin.nick.mapper.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Nick
 * @date 2022/8/3
 */
@Component
public class SystemUserManager {

    @Value("${nick.root-id}")
    private Long rootId;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private SystemUserMapper systemUserMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    private RoleAuthorityMapper roleAuthorityMapper;


    /**
     * 获取rootId
     * @return
     */
    public Long getRootId() {
        return rootId;
    }


    /**
     * 检测Nick用户是否存在
     */
    public void checkNickAndInsert() {
        LambdaQueryWrapper<SystemUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SystemUser::getAccount, "nick").last("limit 1");
        SystemUser systemUser = systemUserMapper.selectOne(queryWrapper);
        if (Objects.isNull(systemUser)) {
            systemUser = new SystemUser();
            systemUser.setUsername("Nick");
            systemUser.setAccount("nick");
            systemUser.setPassword(bCryptPasswordEncoder.encode("nick"));
            systemUser.setTelNumber("13141234567");
            systemUser.setAvatar("https://profile-avatar.csdnimg.cn/9f8584fadd944a348974c258181e8ffe_weixin_45508768.jpg");
            systemUserMapper.insert(systemUser);
        }
    }

    /**
     * 根据用户id获取授权列表
     * @param userId
     * @return
     */
    public List<GrantedAuthority> getGrantedAuthorityListByUserId(Long userId) {
        List<String> authorityString = getAuthorityStringListByUserId(userId);
        List<GrantedAuthority> userGrantedAuthorityList = authorityString.parallelStream()
                .map(key -> new UserGrantedAuthority(key))
                .collect(Collectors.toList());
        return userGrantedAuthorityList;
    }

    /**
     * 根据用户id获取权限字符串列表
     * @param userId
     * @return
     */
    public List<String> getAuthorityStringListByUserId(Long userId) {
        List<Authority> authorityList = getAuthorityListByUserId(userId);
        List<String> authorityKeyList = authorityList.parallelStream()
                .map(Authority::getAuthorityKey)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        return authorityKeyList;
    }

    /**
     * 根据用户id获取权限列表
     * @param userId
     * @return
     */
    public List<Authority> getAuthorityListByUserId(Long userId) {

        List<Authority> authorityList = new ArrayList<>();

        List<Long> roleIdList = getRoleIdListByUserId(userId);

        for (Long roleId : roleIdList) {
            List<Authority> authorityListByRoleId = getAuthorityListByRoleId(roleId);
            authorityList.addAll(authorityListByRoleId);
        }

        authorityList = authorityList.parallelStream().filter(Objects::nonNull).collect(Collectors.toList());
        return authorityList;
    }

    /**
     * 根据角色ie获取权限key列表
     * @param roleId
     * @return
     */
    private List<String> getAuthorityKeyListByRoleId(Long roleId) {

        // 获取到角色列表,遍历出 authorityKey
        List<Authority> authorityList = getAuthorityListByRoleId(roleId);
        if (CollectionUtils.isEmpty(authorityList)) {
            return new ArrayList<>();
        }
        List<String> roleKeyList = authorityList.parallelStream()
                .filter(Objects::nonNull)
                .map(Authority::getAuthorityKey)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return roleKeyList;
    }


    /**
     * 根据角色id获取权限列表
     * @param roleId
     * @return
     */
    private List<Authority> getAuthorityListByRoleId(Long roleId) {

        if (Objects.isNull(roleId)) {
            return new ArrayList<>();
        }

        // 从 角色-权限关联表获取权限id列表
        LambdaQueryWrapper<RoleAuthority> roleAuthorityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleAuthorityLambdaQueryWrapper.eq(RoleAuthority::getRoleId, roleId);
        List<RoleAuthority> roleAuthorityList = roleAuthorityMapper.selectList(roleAuthorityLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(roleAuthorityList)) {
            return new ArrayList<>();
        }
        List<Long> authorityIdList = roleAuthorityList.parallelStream()
                .filter(Objects::nonNull)
                .map(RoleAuthority::getAuthorityId)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(authorityIdList)) {
            return new ArrayList<>();
        }
        // 查询权限列表,根据权限id列表
        List<Authority> authorityList = authorityMapper.selectBatchIds(authorityIdList);

        return authorityList;
    }

    /**
     * 根据用户id获取角色key列表
     * @param userId
     * @return
     */
    public List<String> getRoleKeyListByUserId(Long userId) {

        // 获取到角色列表,遍历出 roleKey
        List<Role> roleList = getRoleListByUserId(userId);
        if (CollectionUtils.isEmpty(roleList)) {
            return new ArrayList<>();
        }
        List<String> roleKeyList = roleList.parallelStream()
                .filter(Objects::nonNull)
                .map(Role::getRoleKey)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return roleKeyList;
    }

    /**
     * 根据用户id获取角色id列表
     * @param userId
     * @return
     */
    public List<Long> getRoleIdListByUserId(Long userId) {

        // 获取到角色列表,遍历出 roleKey
        List<Role> roleList = getRoleListByUserId(userId);
        if (CollectionUtils.isEmpty(roleList)) {
            return new ArrayList<>();
        }
        List<Long> roleIdList = roleList.parallelStream()
                .map(Role::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        return roleIdList;
    }

    /**
     * 根据用户id获取角色列表
     * @param userId
     * @return
     */
    public List<Role> getRoleListByUserId(Long userId) {

        if (Objects.isNull(userId)) {
            return new ArrayList<>();
        }

        // 首先从用户-角色关联中拿到角色id列表,之后获取角色列表
        LambdaQueryWrapper<UserRole> userRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userRoleLambdaQueryWrapper.eq(UserRole::getUserId, userId);
        List<UserRole> userRoleList = userRoleMapper.selectList(userRoleLambdaQueryWrapper);
        if (CollectionUtils.isEmpty(userRoleList)) {
            return new ArrayList<>();
        }
        List<Long> roleIdList = userRoleList.parallelStream()
                .filter(Objects::nonNull)
                .map(UserRole::getRoleId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(roleIdList)) {
            return new ArrayList<>();
        }
        // 获取到角色列表,
        List<Role> roleList = roleMapper.selectBatchIds(roleIdList);
        return roleList;
    }

}
